﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Common;
using Common.Controls;
using Common.Admin;
using System.Windows.Markup;

namespace SL.Participant
{
    public partial class App : Application
    {
        StudyManager _studyManager = StudyManager.GetInstance();
        StudyDataClient _studyDataClient = new StudyDataClient();

        DialogHelper _dialog = new DialogHelper();
        Guid _studyId;
        Study _study;
        Condition _condition;
        List<StudyConsolidatedOrderedIndividualResult> _pages;
        //int _ConditionId;
        //int _StudyWaveId;
        DateTime? _nextWaveStart;
        DateTime? _nextWaveEnd;
        List<FrameworkElement> PageCache = new List<FrameworkElement>();
        public App()
        {
            this.Startup += this.Application_Startup;
            this.Exit += this.Application_Exit;
            this.UnhandledException += this.Application_UnhandledException;

            InitializeComponent();
        }

        private void Application_Startup(object sender, StartupEventArgs e)
        {
            _studyId = new Guid(e.InitParams["studyId"]);
            _dialog.LoginCompleted += new DialogHelper.LoginCompletedDelegate(dialog_LoginCompleted);
            Page NewPage = new Page();
            //I have to set the StudyLoaded property so that my validation routine
            //knows not to validate on LostFocus until the study is loaded
            NewPage.StudyLoaded = false;
            NewPage.NextPageClicked += new Page.NextPageClickedDelegate(NewPage_NextPageClicked);
            NewPage.PreviousPageClicked += new Page.PreviousPageClickedDelegate(NewPage_PreviousPageClicked);
            this.RootVisual = NewPage;
            _dialog.ForceLogin(NewPage.MainGrid,App.Current,_studyId);
        }

        void NewPage_NextPageClicked(List<string> Names, List<string> Values)
        {
            NextPage(Names,Values);
        }

        void NewPage_PreviousPageClicked()
        {
            PreviousPage();
        }

        void dialog_LoginCompleted(bool LoginSuccess, int UserId)
        {            
            _studyDataClient.ResumeStudyEvent += new StudyDataClient.ResumeStudyDelegate(_studyManager_ResumeStudyEvent);
            _studyDataClient.ResumeStudy(UserId, _studyId, false);
            _studyManager.IndividualId = UserId;
        }

        void _studyManager_ResumeStudyEvent(Common.Admin.Condition myCondition, Common.Admin.Study myStudy, DateTime? FutureStartDate, DateTime? FutureEndDate, List<Common.Admin.StudyConsolidatedOrderedIndividualResult> SurveyPages)
        {
            _pages = (from x in SurveyPages
                         orderby x.StudyWaveSurveyDisplayOrder, x.SurveyPageDisplayOrder
                         select x).ToList();
            _studyId = myStudy.StudyId;
            _study = myStudy;
            _condition = myCondition;
            _nextWaveEnd = FutureEndDate;
            _nextWaveStart = FutureStartDate;
            NextPage(null,null);
        }
        private void NextPage(List<string> Names, List<string> Values)
        {
            StudyConsolidatedOrderedIndividualResult CurrentPage = GetCurrentPage();
            StudyConsolidatedOrderedIndividualResult NextPage = null;
            if (CurrentPage == null)
            {
                if (_pages.Count > 0)
                {
                    NextPage = _pages[0];                    
                    BindContent(NextPage);
                    HideShowButtons(NextPage);
                }
                else
                {
                    // Bind finish page
                    BindFinishPage(_nextWaveStart,_nextWaveEnd);
                }                
            }
            else
            {
                // Cache the current page for when the user hits previous button
                CurrentPage.SavedVersion = PageControl.MainContent;
                if (_pages.IndexOf(CurrentPage) < _pages.Count - 1)
                {
                    NextPage = _pages[_pages.IndexOf(CurrentPage) + 1];
                    //See which version to show
                    if (NextPage.SavedVersion == null)
                    {
                        //Show the original version
                        BindContent(NextPage);
                    }
                    else
                    {
                        //Show the saved version
                        BindContent(NextPage.SavedVersion, NextPage);
                    }
                    HideShowButtons(NextPage);
                }
                else
                {
                    //Bind finish page
                    BindFinishPage(_nextWaveStart, _nextWaveEnd);
                }                
            }            
            if ((Names != null) && (Values != null))
            {
                _studyDataClient.ReportSurveyPageResults(
                    CurrentPage.StudyId
                    , CurrentPage.IndividualId
                    , CurrentPage.StudyWaveId
                    , CurrentPage.SurveyId
                    , CurrentPage.SurveyPageId
                    , Names, Values);
            }
            // I set this so I can now validate the controls
            // when the LostFocus event happens.
            PageControl.StudyLoaded = true;
        }
        private void BindFinishPage(DateTime? WaveStart, DateTime? WaveFinish)
        {
            Page_Final FinalPage = new Page_Final(WaveStart, WaveFinish);
            FinalPage.Width = PageControl.ActualWidth;
            FinalPage.Height = PageControl.ActualHeight;
            PageControl.MainGrid.Children.Add(FinalPage);
        }
        private void PreviousPage()
        {
            StudyConsolidatedOrderedIndividualResult CurrentPage = GetCurrentPage();
            StudyConsolidatedOrderedIndividualResult NextPage = _pages[_pages.IndexOf(CurrentPage) - 1];
            // Cache the current page for when the user hits previous button
            CurrentPage.SavedVersion = PageControl.MainContent;
            HideShowButtons(NextPage);
            if (_pages.IndexOf(CurrentPage) != 0)
            {
                //Check for saved version
                if (NextPage.SavedVersion == null)
                {
                    BindContent(NextPage);
                }
                else
                {
                    BindContent(NextPage.SavedVersion, NextPage);
                }
            }            
        }
        private void HideShowButtons(StudyConsolidatedOrderedIndividualResult NextPage)
        {
            if (_pages.IndexOf(NextPage) == 0)
            {
                // First item so can't go back
                PageControl.btnBack.IsEnabled = false;
            }
            else
            {
                PageControl.btnBack.IsEnabled = true;
            }
        }
        private void BindContent(StudyConsolidatedOrderedIndividualResult Page)
        {
            PageControl.AddContent(Page.PageContent);
            PageControl.DataContext = Page;
        }
        private void BindContent(object PageContent,StudyConsolidatedOrderedIndividualResult Page )
        {
            PageControl.AddContent(PageContent);
            PageControl.DataContext = Page;
        }
        private Page PageControl
        {
            get { return this.RootVisual as Page; }
            set { this.RootVisual = value; }
        }
        private StudyConsolidatedOrderedIndividualResult GetCurrentPage()
        {
            return (PageControl).DataContext as StudyConsolidatedOrderedIndividualResult;
        }
        private void Application_Exit(object sender, EventArgs e)
        {

        }
        private void Application_UnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e)
        {
            // If the app is running outside of the debugger then report the exception using
            // the browser's exception mechanism. On IE this will display it a yellow alert 
            // icon in the status bar and Firefox will display a script error.
            if (!System.Diagnostics.Debugger.IsAttached)
            {

                // NOTE: This will allow the application to continue running after an exception has been thrown
                // but not handled. 
                // For production applications this error handling should be replaced with something that will 
                // report the error to the website and stop the application.
                e.Handled = true;

                try
                {
                    string errorMsg = e.ExceptionObject.Message + e.ExceptionObject.StackTrace;
                    errorMsg = errorMsg.Replace('"', '\'').Replace("\r\n", @"\n");

                    System.Windows.Browser.HtmlPage.Window.Eval("throw new Error(\"Unhandled Error in Silverlight 2 Application " + errorMsg + "\");");
                }
                catch (Exception)
                {
                }
            }
        }
    }
}
